﻿using Microsoft.Xna.Framework;
using RaptorEngine.Components;
using RaptorEngine.Components.CollidableComponent;
using RaptorEngine;

namespace OilRigSumoWrestlers.Actions
{
	internal class Floor : CollisionAction
	{
		public Floor(float remainingEnergy)
		{
			RemainingEnergy = new Vector3(remainingEnergy);
			RemainingEnergy.Y = 1;
		}

        /// <summary>
        /// Handles collision between two boundingSpheres with newton physics solid spheres with 1-remainingEnergy lost. 
        /// </summary>
        /// <param name="ownEntity">The parent entity of the action</param>
        /// <param name="ownVolume">The parent bounding volume of the action</param>
        /// <param name="othersEntity">The other colliding entity</param>
        /// <param name="othersVolume">The boundingVolume of the other entity</param>
		public override void HandleCollision(Entity ownEntity, BoundingVolume ownVolume, Entity othersEntity,
									BoundingVolume othersVolume)
        {
			// Add oil particles if entity has support for it and is moving over oil.
			if (othersEntity.HasComponent(ComponentType.Particle) && othersEntity.HasComponent(ComponentType.Movable) && RemainingEnergy.X == GameConstant.OIL_FRICTION)
			{
				Movable moveable = (Movable)othersEntity.GetComponent(ComponentType.Movable);
				// Is the entity moving fast enough over oil to create particles
				if (moveable.Velocity.Length() > 0.02 || moveable.Acceleration != Vector3.Zero)
				{
					ParticleComp part = ((ParticleComp)othersEntity.GetComponent(ComponentType.Particle));
					part.AddParticles("runningOil", othersEntity.Position, Vector3.Zero);
				}
			}

			if (othersEntity.HasComponent(ComponentType.Movable)
				&& othersVolume.CollisionTypes.Contains((int)CollisionType.Bounce))
			{
				Movable otherMovable = (Movable)othersEntity.GetComponent(ComponentType.Movable);
				// Y-axis with negative gravity
				if (othersVolume.Center.Y - othersVolume.Radius * 0.5f > ownVolume.Box.Value.Max.Y)
				{
					otherMovable.Velocity *= RemainingEnergy;
					otherMovable.Velocity = new Vector3(otherMovable.Velocity.X, 0.001f, otherMovable.Velocity.Z);
				}
				// X-axis
				else if (othersVolume.Center.X < ownVolume.Box.Value.Min.X && otherMovable.Velocity.X > 0)
				{
					otherMovable.Velocity = Vector3.Reflect(otherMovable.Velocity, Vector3.Left) * RemainingEnergy;
					othersVolume.IsCalculated = true;
				}
				else if (othersVolume.Center.X > ownVolume.Box.Value.Max.X && otherMovable.Velocity.X < 0)
				{
					otherMovable.Velocity = Vector3.Reflect(otherMovable.Velocity, Vector3.Right) * RemainingEnergy;
					othersVolume.IsCalculated = true;
				}

				// Z-axis
				else if (othersVolume.Center.Z < ownVolume.Box.Value.Min.Z && otherMovable.Velocity.Z > 0)
				{
					otherMovable.Velocity = Vector3.Reflect(otherMovable.Velocity, Vector3.Forward) * RemainingEnergy;
					othersVolume.IsCalculated = true;
				}
				else if (othersVolume.Center.Z > ownVolume.Box.Value.Max.Z && otherMovable.Velocity.Z < 0)
				{
					otherMovable.Velocity = Vector3.Reflect(otherMovable.Velocity, Vector3.Backward) * RemainingEnergy;
					othersVolume.IsCalculated = true;
				}
			}
		}
	}
}

